/*
 *
 * @Author: Jevon
 * @Date: 2021-10-22 18:43:47
 */

class MergeMaps {
  constructor() {
    this.maps = {};
  }

  /**
   * 设置合并信息
   * @param {*} r
   * @param {*} c
   * @return {*}
   */
  set(r, c, span) {
    if (!this.maps[r]) {
      this.maps[r] = {};
    }
    this.maps[r][c] = span;
  }

  /**
   * 按区域设置合并信息
   * @param {*} sr
   * @param {*} sc
   * @param {*} er
   * @param {*} ec
   * @return {*}
   */
  setRange(sr, sc, er, ec) {
    if (er && er > 1) {
      ec = ec || 1;
      // 后续行
      for (let r = 1; r < er; r++) {
        this.set(sr + r, sc, ec);
      }
    }
    // 下一列
    if (ec && ec > 1) {
      this.set(sr, sc + 1, ec - 1);
    }
  }

  /**
   * 获取合并信息
   * @param {*} r
   * @param {*} c
   * @return {*}
   */
  get(r, c) {
    let result = 0;
    if (this.maps[r] && this.maps[r][c]) {
      result = this.maps[r][c];
    }
    return result;
  }
}

/**
 * html字符串 转换为 组件数据格式
 * @param {*} html
 * @return {*}
 */
export function html2sheet(html, cleanRange, createCell, rows, cols) {
  const doc = new DOMParser().parseFromString(html, 'text/html');
  const trs = Array.from(doc.querySelectorAll('table tr'));
  // 记录合并单元格
  const map = new MergeMaps();
  // 只选择1个单元格的时候 按照复制的表格进行粘贴
  const selectOneCell = rows === 1 && cols === 1;
  trs.forEach((tr, ri) => {
    if (selectOneCell || ri < rows) {
      // 创建行
      const tds = tr.querySelectorAll('td');
      let ci = 0;
      tds.forEach(td => {
        if (selectOneCell || ci < cols) {
          const mc = map.get(ri, ci);
          ci = ci + mc;
          const rowSpan = td.rowSpan || 1;
          const colSpan = td.colSpan || 1;
          // 记录合并单元格信息
          map.setRange(ri, ci, rowSpan, colSpan);
          // 清理被合并的单元格
          cleanRange(ri, ci, rowSpan - 1, colSpan - 1);
          // 创建单元格
          createCell(ri, ci, td.innerText);
          ci++;
        }
      });
    }
  });
}

/**
 * 组件数据格式 转换为 html字符串
 * @param {*} range
 * @return {*}
 */
export class sheet2html {
  constructor() {
    this.dom = document.createElement('table');
  }

  createTr(tds = []) {
    const tr = document.createElement('tr');
    tds.forEach(td => {
      tr.appendChild(td);
    });
    this.dom.appendChild(tr);
  }

  createTd(text, rowSpan, colSpan) {
    const td = document.createElement('td');
    td.innerText = text;
    if (rowSpan) td.rowSpan = rowSpan;
    if (colSpan) td.colSpan = colSpan;
    return td;
  }

  getString() {
    return this.dom.outerHTML;
  }
}
